/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package collection;

import dto.Category;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author duonghung1369
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "categories")
public class Categories {

    @XmlElement(name = "category", required = true)
    private List<Category> categories;
    private transient boolean found;
    private transient String deletedIdString;

    public Categories() {
        found = false;
        deletedIdString = "";
    }

    public Categories(List<Category> categories) {
        if (categories == null) {
            categories = new ArrayList<Category>();
        } else {
            this.categories = categories;
        }
        found = false;
        deletedIdString = "";
    }

    /**
     * Update a deleted category status using DOM.
     * @param node root node.
     * @param id categoryId.
     * @param value boolean of deleted node value.
     */
    public void updateDeletedCategory(Node node, int id, boolean value) {
        if (node == null) {
            return;
        }


        if (node.getNodeName().equals("category")) {
            Node attrProductId = node.getAttributes().getNamedItem("id");
            int categoryId = Integer.parseInt(attrProductId.getNodeValue());
            if (categoryId == id) {
                NodeList childrenOfCategory = node.getChildNodes();
                for (int i = 0; i < childrenOfCategory.getLength(); i++) {
                    Node tmp = childrenOfCategory.item(i);
                    if (tmp.getNodeName().equals("deleted")) {
                        tmp.setTextContent(String.valueOf(value));
                        deletedIdString += tmp.getParentNode().getAttributes().getNamedItem("id").getNodeValue() + " ";
//                        found = true;
//                        return;
                    } else if (tmp.getNodeName().equals("parent")) { // also update status of parent node
                        NodeList childrenOfParentCategory = tmp.getChildNodes();
                        for (int j = 0; j < childrenOfParentCategory.getLength(); j++) {
                            Node tmp2 = childrenOfParentCategory.item(j);
                            if (tmp2.getNodeName().equals("deleted")) {
                                tmp2.setTextContent(String.valueOf(value));
                            }
                        }

                        Node categoryOfParent = tmp.getParentNode();
                        NodeList list = categoryOfParent.getChildNodes();
                        for (int j = 0; j < list.getLength(); j++) {
                            Node tmp3 = list.item(j);
                            if (tmp3.getNodeName().equals("deleted")) {
                                tmp3.setTextContent(String.valueOf(value));
                            }
                        }
                        deletedIdString += categoryOfParent.getAttributes().getNamedItem("id").getNodeValue() + " ";
                    }
                }
            }
        }

        // recursion
        int i = 0;
        NodeList children = node.getChildNodes();
        while (i < children.getLength()) {
            updateDeletedCategory(children.item(i++), id, value);
        }
    }

    public void updateDeletedCategory(NodeList categoryNodes, boolean value) {
        Node rootNode;
        // loop for all category node or parent node with id = deleted id
        for (int i = 0; i < categoryNodes.getLength(); i++) {
            rootNode = categoryNodes.item(i);
            if (!deletedIdString.contains(rootNode.getAttributes().getNamedItem("id").getNodeValue().trim())) {
                deletedIdString += rootNode.getAttributes().getNamedItem("id").getNodeValue() + " ";
            }
            NodeList childNodeOfCategory = rootNode.getChildNodes();
            for (int j = 0; j < childNodeOfCategory.getLength(); j++) {
                Node child = childNodeOfCategory.item(j);
                if (child.getNodeName().equals("deleted")) {
                    child.setTextContent(String.valueOf(value));
                } else if (child.getNodeName().equals("parent")) {
                    NodeList childrenOfParentNode = child.getChildNodes();
                    for (int k = 0; k < childrenOfParentNode.getLength(); k++) {
                        Node childOfParent = childrenOfParentNode.item(k);
                        if (childOfParent.getNodeName().equals("deleted")) {
                            childOfParent.setTextContent(String.valueOf(value));
                        }
                    }
                }
            }

            if (rootNode.getNodeName().equals("parent")) {
                Node categoryNode = rootNode.getParentNode();
                NodeList children = categoryNode.getChildNodes();
                for (int j = 0; j < children.getLength(); j++) {
                    if (children.item(j).getNodeName().trim().equals("deleted")) {
                        children.item(j).setTextContent(String.valueOf(value));
                    }
                }
                if (!deletedIdString.contains(categoryNode.getAttributes().getNamedItem("id").getNodeValue())) {
                    deletedIdString += categoryNode.getAttributes().getNamedItem("id").getNodeValue() + " ";
                }
            }
        }
    }

    public List<Category> getCategories() {
        if (categories == null) {
            categories = new ArrayList<Category>();
        }
        return categories;
    }

    public void setCategories(List<Category> categories) {
        this.categories = categories;
    }

    /**
     * @return the found
     */
    public boolean isFound() {
        return found;
    }

    /**
     * @param found the found to set
     */
    public void setFound(boolean found) {
        this.found = found;
    }

    /**
     * @return the deletedIdString
     */
    public String getDeletedIdString() {
        return deletedIdString;
    }

    /**
     * @param deletedIdString the deletedIdString to set
     */
    public void setDeletedIdString(String deletedIdString) {
        this.deletedIdString = deletedIdString;
    }
}
